package com.design.pattern.iterator;

/**
 * 自定义列表
 *
 * @param <T>
 */
public class MyList<T> implements CustomCollection<T> {
    private Object[] datas = {};
    private Object[] tmpDatas;
    int pos = -1;

    @Override
    public CustomIterator<T> iterator() {
        return new MyListIterator<T>(this);
    }

    @Override
    public boolean add(T t) {
        if (datas.length == 0 || pos == datas.length - 1) {
            copyValuesAdd();
        }
        pos += 1;
        datas[pos] = t;
        return true;
    }

    /**
     * 移除元素
     * @param t 元素
     * @return
     */
    @Override
    public boolean remove(T t) {

        if (pos == 0) {
            //如果当前不存在元素,移除元素失败
            return false;
        }
        boolean reduce = true;
        //遍历当前集合,判断是否存在指定元素
        int position= at(t);//获取指定元素的位置

        if (position==-1){
            //当前元素不存在
            return false;
        }
        //移除该元素,同时,将元素后面的数据前移一位.

        for (int i=position;i<=pos;i++){
            //移除元素,直接使用下一个元素覆盖
            int j=i+1;
            if (i==pos){
                datas[i]=null;
            }else{
                datas[i]=datas[j];
            }


        }
        pos--;
        //判断此时数据的长度,是否需要减少数组的长度
        if (size() * 2 == datas.length) {
            copyValuesReduce();
        }
        return true;
    }

    @Override
    public boolean update(T t1, T t2) {
        int p = at(t1);
        if (p == -1) {
            return false;
        }
        datas[p] = t2;
        return true;

    }

    @Override
    public int size() {
        return pos + 1;
    }

    private void copyValuesAdd() {
        //扩容2倍,第一次为10
        tmpDatas = new Object[datas.length == 0 ? 10 : datas.length << 1];
        for (int i = 0; i < datas.length; i++) {
            tmpDatas[i] = datas[i];
        }
        datas = tmpDatas;
        tmpDatas = null;
    }

    private void copyValuesReduce() {
        //判断新数组长度
        tmpDatas = new Object[size() == 0 ? 0 : datas.length >> 1];
        for (int i = 0; i < size(); i++) {
            tmpDatas[i] = datas[i];
        }
        datas = tmpDatas;
        tmpDatas = null;
    }

    @Override
    public T get(T t) {
        for (int i = 0; i < pos; i++) {
            if (t.equals(datas[i])) {
                return (T) datas[i];
            }
        }
        return null;
    }

    @Override
    public int at(T t) {
        for (int i = 0; i < size(); i++) {
            if (t.equals(datas[i])) {
                return i;
            }
        }
        return -1;
    }

    @Override
    public T indexOf(int p) {

        return p <= pos ? (T) datas[p] : null;
    }
}
